// Draw a 3-d ball and move it
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <iostream>
#include <math.h>
  
double user_theta  = 0;
double user_height = 0;


void computeLocation() {
       double x = 2 * cos(user_theta);     // my x-, y-, and z-coordinates
       double y = 2 * sin(user_theta);
       double z = user_height;
       double d = sqrt(x * x + y * y + z * z); // distance to origin
  
       glMatrixMode(GL_PROJECTION);        // Set projection parameters.
       glLoadIdentity();
       glFrustum(-d * 0.5, d * 0.5, -d * 0.5, d * 0.5, d - 1.1, d + 1.1);
       gluLookAt(x,y,z,  0, 0, 0,  0, 0, 1);
}

void myInit( void )  {
  	 GLfloat sun_direction[] = { 0.0, 2.0, -1.0, 1.0 };
       GLfloat sun_intensity[] = { 0.7, 0.7, 0.7, 1.0 };
       GLfloat ambient_intensity[] = { 0.3, 0.3, 0.3, 1.0 };
  
       glClearColor(1.0, 1.0, 1.0, 0.0);   // Set window color to white.
       computeLocation();
  
       glEnable(GL_DEPTH_TEST);            // Draw only closest surfaces
  
       glEnable(GL_LIGHTING);              // Set up ambient light.
       glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_intensity);
  
       glEnable(GL_LIGHT0);                // Set up sunlight.
       glLightfv(GL_LIGHT0, GL_POSITION, sun_direction);
       glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_intensity);
  
       glEnable(GL_COLOR_MATERIAL);        // Configure glColor().
       glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
}

void myDisplay( void )  {
	  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear window.
       glColor3f(1.0, 1.0, 1.0);
       glShadeModel(GL_SMOOTH);
       glutSolidSphere(1.0, 50, 50);
            
       glutSwapBuffers();
}

// Called when a "special" key is pressed
void special(int k, int x, int y) {
    switch(k) {
    case GLUT_KEY_UP:    user_height += 0.1; break;
    case GLUT_KEY_DOWN:  user_height -= 0.1; break;
    case GLUT_KEY_LEFT:  user_theta  += 0.1; break;
    case GLUT_KEY_RIGHT: user_theta  -= 0.1; break;
    }
    computeLocation();
    glutPostRedisplay();
   }
int main( int argc, char *argv[] )  {
  glutInit( &argc, argv );
  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize( 500, 500 );
  glutInitWindowPosition( 50, 100 );
  glutCreateWindow( "Ball" );
  glutDisplayFunc( myDisplay );
  glutSpecialFunc(special);
  myInit( );
  glutMainLoop( );
}

/* ----------------------------------------------------------------------- */
